package org.example.mq.mqserver.core;

/*
   表示存储消息的队列
 */

import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.Data;
import lombok.NoArgsConstructor;

import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicInteger;

@Data
@NoArgsConstructor
@TableName("queue")
public class MessageQueue {
    @TableId(type = IdType.INPUT)
    //标识
    private String name;
    //是否持久化
    private boolean durable = false;
    //是否独占
    private boolean exclusive = false;
    //自动删除
    private boolean autoDelete = false;
    //扩展参数
    private Map<String,Object> arguments  = new HashMap<>();
    //当前队列有哪些订阅者
    @TableField(exist = false)
    private List<ConsumerEnv> consumerEnvList = new ArrayList<>();
    //当前轮询消费者下标
    @TableField(exist = false)
    private AtomicInteger consumerIndex = new AtomicInteger(0);
    //检查是否重复订阅
    @TableField(exist = false)
    private final Set<String> consumerTags = new HashSet<>();
    @TableField(exist = false)
    // 新增一个 map 保存 consumerTag → channelId
    private Map<String, String> consumerTagChannelMap = new ConcurrentHashMap<>();

    public void addConsumerEnv(ConsumerEnv consumerEnv){
        synchronized (this){
            if (!consumerTags.add(consumerEnv.getConsumerTag())) {
                // tag 已存在，直接跳过
                System.out.println("消费者 " + consumerEnv.getConsumer() + " 已经存在，跳过注册");
                return;
            }
            consumerTagChannelMap.put(consumerEnv.getConsumerTag(), consumerEnv.getChannelId());
            consumerEnvList.add(consumerEnv);
        }
    }

    public String getChannelIdByConsumerTag(String consumerTag) {
        return consumerTagChannelMap.get(consumerTag);
    }

    public ConsumerEnv chooseConsumer(){
        int size = consumerEnvList.size();
        if(size == 0){
            //没有消费者订阅
            return null;
        }

        int index = consumerIndex.getAndUpdate(i -> (i + 1) % size);
        return consumerEnvList.get(index);
    }

    //将arguments转换成json字符串 方便存储到数据库
    public String getArguments(){
        ObjectMapper mapper = new ObjectMapper();
        try {
            return mapper.writeValueAsString(arguments);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return "{}";
    }

    //设置数据库返回的arguments json转换成map
    public void setArguments(String arguments){
        ObjectMapper mapper = new ObjectMapper();
        try {
            this.arguments = mapper.readValue(arguments, new TypeReference<Map<String,Object>>(){});
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public MessageQueue(String name, boolean durable, boolean exclusive, boolean autoDelete, Map<String, Object> arguments) {
        this.name = name;
        this.durable = durable;
        this.exclusive = exclusive;
        this.autoDelete = autoDelete;
        this.arguments = arguments;
    }

    public Object getArgument(String key){
        return arguments.get(key);
    }

    public void setArgument(String key, Object value) {
        arguments.put(key, value);
    }

    public void setArguments(Map<String, Object> arguments) {
        this.arguments = arguments;
    }

}
